home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Game-Power
/
Amiga Game-Power.iso
/
pd mix ii
/
access
/
hddriver
/
support
/
initiate.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-20
|
12KB
|
489 lines
#include <stdio.h>
#include "hd.h"
char rbuf[ HD_SECTOR ];
char wbuf[ HD_SECTOR ];
FILE *input;
FILE *logfile;
main ( argc , argv )
int argc;
char **argv;
{
char *commands;
int done_write;
int status;
if ( argc != 3 && argc != 4 )
usage ();
if ( argc > 3 ) {
input = fopen ( argv[3] , "r" );
if ( input == NULL ) {
fprintf ( stderr , "Failed to open '%s'\n" );
usage ();
}
}
else
input = NULL;
logfile = fopen ( argv[1] , "w" );
if ( logfile == NULL ) {
printf ( "Failed to create logfile %s\n" , argv[1] );
usage ();
}
init_wbuf ();
status = wd_open ();
if ( status != 0 ) {
fprintf ( stderr , "wd_open() failed - returned %d\n" , status );
fprintf ( stderr , "continue(y/n)? " );
if ( getchar () != 'y' ) {
wd_close ();
exit ( 1 );
}
}
commands = argv[2];
if ( *commands == 'f' || *commands == 'F' ) {
if ( input == NULL ) {
fprintf ( stderr , "Inputfile must be specified when formatting a disk\n" );
usage ();
}
printf ( "Formatting disk\n" );
fprintf ( logfile , "Formatting disk\n" );
init_first_sector ();
format_disk ();
commands++;
}
else {
if ( input != NULL )
fprintf ( stderr , "warning: inputfile only used when disk is reformatted\n" );
read_first_sector ();
if ( first.magic != HD_MAGIC ) {
fprintf ( stderr , "incorrect magic number in sector\n" );
wd_close ();
exit ( 1 );
}
}
done_write = 0;
while ( *commands != '\0' ) {
switch ( *commands++ ) {
case 'r' :
case 'R' :
printf ( "Reading disk\n" );
fprintf ( logfile , "Reading disk\n" );
read_disk ( done_write );
break;
case 'w' :
case 'W' :
printf ( "Writing disk\n" );
fprintf ( logfile , "Pass 3: Writing disk\n" );
write_disk ();
done_write = 1;
break;
default :
usage ();
}
}
printf ( "Done - writing bad sector table to disk\n" );
dump_first_sector ();
printf ( "\n%d sectors used for map information\n" , HD_MAP_SECTORS );
printf ( "%ld sectors used so far for relinking bad sectors\n" ,
(long)first.bad_sectors );
printf ( "%ld tracks would be required to hold these sectors\n\n" ,
(long)( HD_MAP_SECTORS + first.bad_sectors - 1 ) / first.sectors + 1 );
printf ( "A total of %d sectors could be used for relinking bad sectors\n" ,
HD_MAP_SECTORS + HD_MAP_SIZE );
printf ( "This would require %ld reserved tracks\n" ,
(long) ( HD_MAP_SECTORS + HD_MAP_SIZE - 1 ) / first.sectors + 1 );
fclose ( logfile );
wd_close ();
}
usage ()
{
fprintf ( stderr , "Usage: initiate logfile commands [inputfile]\n" );
fprintf ( stderr , "The commands consist of a series of command characters\n" );
fprintf ( stderr , "If the first character is a 'f' then the hard disk is formatted\n" );
fprintf ( stderr , "and the map table is rebuilt from the input file\n" );
fprintf ( stderr , "If the following characters are 'r' or 'w' the entire hard disk\n" );
fprintf ( stderr , "is read or written to and any errors added to the map table\n" );
wd_close ();
exit ( 1 );
}
init_first_sector ()
{
int i;
UBYTE *p;
long interleave_factor;
struct posn posn;
char buf[ 128 ];
if ( fgets ( buf , sizeof(buf) , input ) != NULL
&& sscanf ( buf , "%ld" , &first.cylinders ) != 1 ) {
fprintf ( stderr , "Failed to read number of cylinders\n" );
usage ();
}
if ( fgets ( buf , sizeof(buf) , input ) != NULL
&& sscanf ( buf , "%ld" , &first.park_cylinder ) != 1 ) {
fprintf ( stderr , "Failed to read parking cylinder\n" );
usage ();
}
if ( fgets ( buf , sizeof(buf) , input ) != NULL
&& sscanf ( buf , "%ld" , &first.heads ) != 1 ) {
fprintf ( stderr , "Failed to read number of heads (surfaces)\n" );
usage ();
}
if ( fgets ( buf , sizeof(buf) , input ) != NULL
&& sscanf ( buf , "%ld" , &first.sectors ) != 1 ) {
fprintf ( stderr , "Failed to read number of sectors\n" );
usage ();
}
if ( fgets ( buf , sizeof(buf) , input ) != NULL
&& sscanf ( buf , "%ld" , &interleave_factor ) != 1 ) {
fprintf ( stderr , "Failed to read interleave factor\n" );
usage ();
}
first.magic = HD_MAGIC;
first.map_sectors = HD_MAP_SECTORS;
first.bad_sectors = 0;
fprintf ( logfile , "%3ld cylinders\n" , first.cylinders );
fprintf ( logfile , "%3ld park cylinder\n" , first.park_cylinder );
fprintf ( logfile , "%3ld heads\n" , first.heads );
fprintf ( logfile , "%3ld sectors\n" , first.sectors );
fprintf ( logfile , "%3ld interleave factor\n" , interleave_factor );
p = &first.pad[0];
for ( i = 0; i < sizeof ( first.pad ); i++ )
*p++ = 0x55;
new_interleave ( interleave_factor );
for ( i = 0; i < HD_MAP_SIZE; i++ )
first.map[i] = MAP_MARK_FREE;
while ( fgets ( buf , sizeof(buf) , input ) != NULL ) {
switch ( sscanf ( buf , "%ld %ld %ld\n" ,
&posn.cylinder , &posn.surface , &posn.sector ) ) {
case 2 :
for ( posn.sector = 0; posn.sector < first.sectors; posn.sector++ ) {
posn.block = posn.sector
+ ( posn.surface * first.sectors )
+ ( posn.cylinder * first.sectors * first.heads );
bad_sector ( &posn , 0 , "input" );
}
break;
case 3 :
posn.block = posn.sector
+ ( posn.surface * first.sectors )
+ ( posn.cylinder * first.sectors * first.heads );
bad_sector ( &posn , 0 , "input" );
break;
default :
fprintf ( stderr , "Error in bad sector file\n" );
wd_close ();
exit ( 1 );
}
}
}
read_first_sector ()
{
int i;
char *p;
struct posn posn;
posn.cylinder = 0;
posn.surface = 0;
posn.sector = 0;
posn.block = 0;
p = (char*) &first;
for ( i = 0; i < HD_MAP_SECTORS; i++ ) {
if ( read_sector ( &posn , p ) != 0 ) {
fprintf ( stderr , "Read error when reading map sector %d\n" , i );
wd_close ();
exit ( 1 );
}
posn.sector++;
posn.block++;
p += HD_SECTOR;
}
if ( first.magic != HD_MAGIC ) {
fprintf ( stderr , "Incorrect magic number in bad sector map\n" );
fprintf ( stderr , "Want %08lx, Found %08lx\n" ,
(long)HD_MAGIC , (long)first.magic );
wd_close ();
exit ( 1 );
}
if ( first.map_sectors != HD_MAP_SECTORS ) {
fprintf ( stderr , "error: differing number of map sectors\n" );
fprintf ( stderr , "(program is hard coded for %d sectors, disk wants %d sectors\n" ,
HD_MAP_SECTORS , (int)first.map_sectors );
wd_close ();
exit ( 1 );
}
fprintf ( logfile , "%3ld cylinders\n" , first.cylinders );
fprintf ( logfile , "%3ld park cylinder\n" , first.park_cylinder );
fprintf ( logfile , "%3ld heads\n" , first.heads );
fprintf ( logfile , "%3ld sectors\n" , first.sectors );
}
init_wbuf ()
{
int i;
for ( i = 0; i < HD_SECTOR; i++ )
wbuf[i] = i;
}
format_disk ()
{
struct posn posn;
int status;
int i;
for ( posn.cylinder = 0; posn.cylinder < first.cylinders; posn.cylinder++ ) {
printf ( "%03ld " , posn.cylinder );
for ( posn.surface = 0; posn.surface < first.heads; posn.surface++ ) {
posn.sector = 0;
posn.block = posn.sector
+ ( posn.surface * first.sectors )
+ ( posn.cylinder * first.sectors * first.heads );
printf ( "%ld " , posn.surface );
fflush ( stdout );
wd_format_track ( &posn );
}
printf ( "\n" );
}
}
read_disk ( check )
int check;
{
struct posn posn;
int status;
int i;
for ( posn.cylinder = 0; posn.cylinder < first.cylinders; posn.cylinder++ ) {
printf ( "%03ld " , posn.cylinder );
fflush ( stdout );
for ( posn.surface = 0; posn.surface < first.heads; posn.surface++ ) {
/*
printf ( "%03ld %ld " , posn.cylinder , posn.surface );
fflush ( stdout );
*/
for ( posn.sector = 0; posn.sector < first.sectors; posn.sector++ ) {
posn.block = posn.sector
+ ( posn.surface * first.sectors )
+ ( posn.cylinder * first.sectors * first.heads );
if ( is_bad ( &posn ) ) {
/*
putchar ( 's' );
fflush ( stdout );
*/
continue;
}
/*
putchar ( '.' );
fflush ( stdout );
*/
status = read_sector ( &posn , rbuf );
if ( status != 0 )
bad_sector ( &posn , status , "read" );
if ( check ) {
if ( ! cmp_equal ( rbuf , wbuf ) )
bad_sector ( &posn , 0 , "compare" );
}
}
/*
printf ( "\n" );
*/
}
}
}
write_disk ()
{
struct posn posn;
int status;
int i;
for ( posn.cylinder = 0; posn.cylinder < first.cylinders; posn.cylinder++ ) {
for ( posn.surface = 0; posn.surface < first.heads; posn.surface++ ) {
printf ( "%03ld %ld " , posn.cylinder , posn.surface );
fflush ( stdout );
for ( posn.sector = 0; posn.sector < first.sectors; posn.sector++ ) {
posn.block = posn.sector
+ ( posn.surface * first.sectors )
+ ( posn.cylinder * first.sectors * first.heads );
if ( is_bad ( &posn ) ) {
putchar ( 's' );
fflush ( stdout );
continue;
}
putchar ( '.' );
fflush ( stdout );
status = write_sector ( &posn , wbuf );
if ( status != 0 )
bad_sector ( &posn , status , "write" );
}
printf ( "\n" );
}
}
}
bad_sector ( posn , status , msg )
struct posn *posn;
int status;
char *msg;
{
fprintf ( logfile ,
"%s: Cylinder %ld, Head %ld, Sector %ld: Status %d\n" ,
msg , posn->cylinder , posn->surface , posn->sector , status );
printf ( "\n%s: Cylinder %ld, Head %ld, Sector %ld: Status %d\n" ,
msg , posn->cylinder , posn->surface , posn->sector , status );
/* ok, now add it to the table of bad sectors */
while ( first.bad_sectors < HD_MAP_SIZE
&& first.map[ first.bad_sectors ] == MAP_MARK_BAD )
first.bad_sectors++;
if ( first.bad_sectors < HD_MAP_SIZE ) {
first.map[ first.bad_sectors++ ] = posn->block;
}
else {
fprintf ( logfile , " Overflow: Too many bad sectors!\n" );
printf ( " Overflow: Too many bad sectors!\n" );
}
/* if a bad sector, mark the bad map table so dont try and replace */
/* a bad sector with a bad sector */
if ( posn->block < HD_MAP_SECTORS ) {
printf ( "FATAL ERROR! bad sector in map table\n" );
fprintf ( logfile , "FATAL ERROR! bad sector in map table\n" );
}
else if ( posn->block < HD_MAP_SECTORS + HD_MAP_SIZE )
first.map[ posn->block - HD_MAP_SECTORS ] = MAP_MARK_BAD;
}
cmp_equal ( buf1 , buf2 )
register char *buf1 , *buf2;
{
register int i;
for ( i = 0; i < HD_SECTOR; i++ )
if ( buf1[i] != buf2[i] )
return ( 0 );
return ( 1 );
}
dump_first_sector ()
{
struct posn posn;
int i , j;
LONG *pl;
char *p;
int count;
fprintf ( logfile , "\nInitial Sector\n" );
pl = (LONG*) &first;
for ( i = 0; i < sizeof(first)/sizeof(long); i++ ) {
fprintf ( logfile , "%08lx " , *pl++ );
if ( ( i + 1 ) % 8 == 0 )
fprintf ( logfile , "\n" );
}
fprintf ( logfile , "\n" );
posn.surface = 0;
posn.cylinder = 0;
posn.sector = 0;
posn.block = 0;
p = (char*) &first;
count = HD_MAP_SECTORS;
while ( count-- > 0 ) {
if ( write_sector ( &posn , p ) != 0 )
fprintf ( stderr , "Failed to write map sector %d\n" ,
posn.sector );
posn.sector++;
posn.block++;
p += HD_SECTOR;
}
}
is_bad ( posn )
struct posn *posn;
{
int i;
for ( i = 0; i < first.bad_sectors; i++ ) {
if ( posn->block == first.map[ i ] )
return ( 1 );
}
return ( 0 );
}
new_interleave ( interleave )
long interleave;
{
int i;
int j;
for ( i = 0; i < first.sectors; i++ )
first.interleave[i*2+1] = first.sectors; /* mark as free */
j = 0;
for ( i = 0; i < first.sectors; i++ ) {
while ( first.interleave[j*2+1] != first.sectors ) {
j++;
while ( j >= first.sectors ) j -= first.sectors;
}
first.interleave[j*2+1] = i;
j += interleave;
while ( j >= first.sectors ) j -= first.sectors;
}
for ( i = 0; i < first.sectors; i++ )
printf ( "%d " , first.interleave[i*2+1] );
printf ( "\n" );
}